package label

import (
	"context"
	"gitee.com/bobo-rs/idea-space-framework/enums"
	"gitee.com/bobo-rs/idea-space-framework/framework/dao"
	"gitee.com/bobo-rs/idea-space-framework/framework/model"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"strings"
)

// ProcessLabelIdxList 处理并获取标签索引列表
func (l *sLabel) ProcessLabelIdxList(ctx context.Context, where, list interface{}) error {
	if where == nil || g.IsNil(where) {
		return gerror.New(`请求参数不存在`)
	}
	return dao.LabelIdx.Ctx(ctx).
		Where(where).
		Scan(list)
}

// CheckLabelIdxExists 检测标签索引是否存在
func (l sLabel) CheckLabelIdxExists(ctx context.Context, where interface{}) (bool, error) {
	if where == nil || g.IsNil(where) {
		return false, gerror.New(`请求参数不存在`)
	}
	total, err := dao.LabelIdx.Ctx(ctx).Where(where).Count()
	if err != nil {
		return false, err
	}
	return total > 0, nil
}

// CheckLabelIdxExistsByCidAndType 通过关联ID和类型检测标签索引是否存在
func (l *sLabel) CheckLabelIdxExistsByCidAndType(ctx context.Context, cid, cType uint) (bool, error) {
	return l.CheckLabelIdxExists(ctx, g.Map{
		dao.LabelIdx.Columns().CorrelateId:   cid,
		dao.LabelIdx.Columns().CorrelateType: cType,
	})
}

// ProcessLabelIdxHashAndIdMap 处理并获取标签索引ID和Hash值MAP
func (l *sLabel) ProcessLabelIdxHashAndIdMap(ctx context.Context, cid, cType uint, hash ...string) (map[string]uint, error) {
	if cid == 0 {
		return nil, gerror.New(`获取标签索引缺少关联ID`)
	}
	where := g.Map{
		dao.LabelIdx.Columns().CorrelateId:   cid,
		dao.LabelIdx.Columns().CorrelateType: cType,
	}
	// 标签索引
	if len(hash) > 0 {
		where[dao.LabelIdx.Columns().LabelHash] = hash
	}
	var (
		idxs []model.LabelIdxHashAndIdItem
	)
	err := l.ProcessLabelIdxList(ctx, where, &idxs)
	if err != nil {
		return nil, err
	}
	// 数据为空
	if len(idxs) == 0 {
		return nil, nil
	}
	idxMap := make(map[string]uint)
	for _, idx := range idxs {
		idxMap[idx.LabelHash] = idx.Id
	}
	return idxMap, nil
}

// ProcessLabelIdxHashByCid 根据索引类型和Hash值获取关联ID
func (l *sLabel) ProcessLabelIdxHashByCid(ctx context.Context, cType enums.CorrelateTypeEnums, hash ...string) ([]uint, error) {
	if len(hash) == 0 {
		return nil, gerror.New(`缺少标签索引Hash值`)
	}
	var (
		idxValues []model.LabelIdxCidAndHashItem
		uni       = make(map[uint]bool)
		cits      = make([]uint, 0)
	)
	// 获取数据
	err := l.ProcessLabelIdxList(ctx, g.Map{
		dao.LabelIdx.Columns().CorrelateType: cType,
		dao.LabelIdx.Columns().LabelHash:     hash,
	}, &idxValues)
	if err != nil {
		return nil, err
	}
	// 数据为空
	if len(idxValues) == 0 {
		return nil, gerror.New(`Label Idx Data Empty`)
	}
	for _, idx := range idxValues {
		// 存在-直接返回
		if ok := uni[idx.CorrelateId]; ok {
			continue
		}
		cits = append(cits, idx.CorrelateId)
		uni[idx.CorrelateId] = true // 避免重复
	}
	return cits, nil
}

// ProcessLabelIdxTypeAndHashByCid 通过关联类型和Hash值获取标签值关联ID-切片数组
func (l *sLabel) ProcessLabelIdxTypeAndHashByCid(ctx context.Context, cType enums.CorrelateTypeEnums, value string) ([]uint, error) {
	// 获取Hash值
	hasher := l.GenIdxHash(strings.Split(value, "-"))
	if len(hasher) == 0 {
		return nil, gerror.New(`缺少标签索引Hash值`)
	}
	return l.ProcessLabelIdxHashByCid(ctx, cType, hasher...)
}

// ProcessIdxTypeAndHashByCid 通过关联类型和Hash值获取标签值关联ID-单Hash值
func (l *sLabel) ProcessIdxTypeAndHashByCid(ctx context.Context, cType enums.CorrelateTypeEnums, value string) ([]uint, error) {
	hasher := l.GenHash(value)
	if len(hasher) == 0 {
		return nil, gerror.New(`缺少标签值`)
	}
	return l.ProcessLabelIdxHashByCid(ctx, cType, hasher)
}
